package com.pokermind.dse.tcp.router;

import com.pokermind.dse.tcp.protocol.ProtocolConstants;
import com.pokermind.dse.tcp.protocol.ProtocolMessage;
import com.pokermind.dse.tcp.service.HandManagementService;
import com.pokermind.dse.tcp.service.AIAnalysisService;
import com.pokermind.dse.tcp.service.SystemService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import jakarta.annotation.PostConstruct;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Message Router
 * 消息路由器，负责将协议消息路由到对应的业务服务
 * 
 * 路由规则：
 * 1. Hand Management (1000-1999) -> HandManagementService
 * 2. AI Analysis (2000-2999) -> AIAnalysisService  
 * 3. System (9000-9999) -> SystemService
 * 4. Error (8000-8999) -> 直接处理
 * 
 * 性能特性：
 * 1. 异步处理，避免阻塞I/O线程
 * 2. 线程池隔离，防止业务阻塞
 * 3. 快速失败，无效协议立即返回错误
 * 
 * @author PokerMind Team
 */
@Component
public class MessageRouter {

    private static final Logger logger = LoggerFactory.getLogger(MessageRouter.class);

    @Autowired
    private HandManagementService handManagementService;

    @Autowired
    private AIAnalysisService aiAnalysisService;

    @Autowired
    private SystemService systemService;

    // 业务处理线程池
    private Executor businessExecutor;

    @PostConstruct
    public void initialize() {
        // 创建业务处理线程池
        int processors = Runtime.getRuntime().availableProcessors();
        businessExecutor = Executors.newFixedThreadPool(
                processors * 4, 
                r -> {
                    Thread t = new Thread(r, "tcp-business-" + System.currentTimeMillis());
                    t.setDaemon(true);
                    return t;
                }
        );
        
        logger.info("MessageRouter initialized with {} business threads", processors * 4);
    }

    /**
     * 路由消息到对应的业务服务
     */
    public CompletableFuture<ProtocolMessage> routeMessage(ProtocolMessage message) {
        if (message == null) {
            return CompletableFuture.completedFuture(
                    ProtocolMessage.createErrorResponse(null, 400, "Message is null"));
        }

        short protocolId = message.getProtocolId();
        
        // 验证协议ID
        if (!ProtocolConstants.isValidProtocol(protocolId)) {
            logger.warn("Invalid protocol ID: {} from {}", protocolId, message.getClientId());
            return CompletableFuture.completedFuture(
                    ProtocolMessage.createErrorResponse(message, 400, "Invalid protocol ID"));
        }

        // 验证是否为请求协议
        if (!ProtocolConstants.isRequest(protocolId)) {
            logger.warn("Received non-request protocol: {} from {}", 
                    message.getProtocolName(), message.getClientId());
            return CompletableFuture.completedFuture(
                    ProtocolMessage.createErrorResponse(message, 400, "Expected request protocol"));
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Routing message: {} from {}", message.getProtocolName(), message.getClientId());
        }

        // 根据协议类型路由到对应服务
        try {
            if (ProtocolConstants.isHandManagementProtocol(protocolId)) {
                return routeToHandManagement(message);
            } else if (ProtocolConstants.isAIAnalysisProtocol(protocolId)) {
                return routeToAIAnalysis(message);
            } else if (ProtocolConstants.isSystemProtocol(protocolId)) {
                return routeToSystem(message);
            } else {
                logger.error("Unhandled protocol type: {} for {}", 
                        message.getProtocolType(), message.getProtocolName());
                return CompletableFuture.completedFuture(
                        ProtocolMessage.createErrorResponse(message, 500, "Unhandled protocol type"));
            }
        } catch (Exception e) {
            logger.error("Error routing message {}: {}", message.getProtocolName(), e.getMessage(), e);
            return CompletableFuture.completedFuture(
                    ProtocolMessage.createErrorResponse(message, 500, "Internal routing error"));
        }
    }

    /**
     * 路由到手牌管理服务
     */
    private CompletableFuture<ProtocolMessage> routeToHandManagement(ProtocolMessage message) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return handManagementService.processMessage(message);
            } catch (Exception e) {
                logger.error("Hand management service error: {}", e.getMessage(), e);
                return ProtocolMessage.createBusinessErrorResponse(message, 
                        "Hand management error", e.getMessage());
            }
        }, businessExecutor);
    }

    /**
     * 路由到AI分析服务
     */
    private CompletableFuture<ProtocolMessage> routeToAIAnalysis(ProtocolMessage message) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return aiAnalysisService.processMessage(message);
            } catch (Exception e) {
                logger.error("AI analysis service error: {}", e.getMessage(), e);
                return ProtocolMessage.createBusinessErrorResponse(message, 
                        "AI analysis error", e.getMessage());
            }
        }, businessExecutor);
    }

    /**
     * 路由到系统服务
     */
    private CompletableFuture<ProtocolMessage> routeToSystem(ProtocolMessage message) {
        // 系统消息通常比较轻量，可以同步处理
        return CompletableFuture.completedFuture(systemService.processMessage(message));
    }

    /**
     * 获取路由统计信息
     */
    public RouterStats getRouterStats() {
        // TODO: 实现路由统计
        return new RouterStats();
    }

    /**
     * 路由统计信息
     */
    public static class RouterStats {
        private long handManagementCount = 0;
        private long aiAnalysisCount = 0;
        private long systemCount = 0;
        private long errorCount = 0;

        // Getters
        public long getHandManagementCount() { return handManagementCount; }
        public long getAiAnalysisCount() { return aiAnalysisCount; }
        public long getSystemCount() { return systemCount; }
        public long getErrorCount() { return errorCount; }

        @Override
        public String toString() {
            return String.format(
                    "RouterStats{hand=%d, ai=%d, system=%d, error=%d}",
                    handManagementCount, aiAnalysisCount, systemCount, errorCount
            );
        }
    }
}
